package com.lm56.web.express;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lm56.common.exception.ExpressException;
import com.lm56.web.queryhistory.QueryHistory;
import com.lm56.web.queryhistory.QueryHistoryService;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


import java.io.IOException;
import java.util.*;

/**
 * Created by Kelvin Yeung on 2016/11/16.
 */
@Component
public class ExpressService {


    Logger logger = LoggerFactory.getLogger(ExpressService.class);

    private static final String API_HOST = "http://ali-deliver.showapi.com";
    private static final String EXP_INFO_PATH = "/showapi_expInfo";
    private static final String EXP_LIST_PATH = "/showapi_expressList";

    private static final String EXP_METHOD = "GET";
    private static final String EXP_APP_CODE = "892cfd371f6842a0ae1f50eb554b2864";


    @Autowired
    ExpressMapper expressMapper;
    @Autowired
    QueryHistoryService queryHistoryService;

    public Map getExpInfo(String com, String nu) {

        Map<String, String> headers = new HashMap<String, String>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + EXP_APP_CODE);
        Map<String, String> querys = new HashMap<String, String>();
//        querys.put("com", "shentong");
//        querys.put("nu", "968018776110");
        querys.put("com", com);
        querys.put("nu", nu);


        try {
            /**
             * 重要提示如下:
             * HttpUtils请从
             * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/src/main/java/com/aliyun/api/gateway/demo/util/HttpUtils.java
             * 下载
             *
             * 相应的依赖请参照
             * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/pom.xml
             */
            HttpResponse response = HttpUtils.doGet(API_HOST, EXP_INFO_PATH, EXP_METHOD, headers, querys);
            System.out.println(response.toString());

            StatusLine statusLine = response.getStatusLine();
            if (statusLine.getStatusCode() != 200) {
                //获取失败则返回
                logger.info("get express list failure.:", statusLine.getStatusCode(), statusLine.getReasonPhrase());
                throw new ExpressException("暂无记录");
            }

            //解释结果
            ObjectMapper ob = new ObjectMapper();
            try {
                String result = EntityUtils.toString(response.getEntity());
                JsonNode node = ob.readTree(result);
                JsonNode status = node.get("showapi_res_code");
                if (status.intValue() != 0) {
                    JsonNode error = node.get("showapi_res_error");
                    throw new ExpressException("暂无记录:");
                }
                JsonNode resBodyNode = node.get("showapi_res_body");
                JsonNode queryStatus = resBodyNode.get("status");
                if (queryStatus.intValue() > 1) {
                    //记录查询历史
                    Express express = expressMapper.getExpressBySimpleName(com);
                    if (express != null && express.getExpName() != null) {
                        queryHistoryService.log(nu, express.getExpName(), QueryHistory.TYPE_EXPRESS);
                    }

                }

                Map resultMap = ob.readValue(resBodyNode.toString(), Map.class);

                return resultMap;
            } catch (IOException e) {
                e.printStackTrace();
                throw new ExpressException("暂无记录", e);
            }

        } catch (Exception e) {
            e.printStackTrace();
            throw new ExpressException("暂无记录", e);
        }


    }


    public List<Express> getExpressList() {

        return expressMapper.getExpressList();
    }


    /**
     * 同步快递公司列表
     */
    public void syncExpressList() {

        Map<String, String> headers = new HashMap<String, String>();
        headers.put("Authorization", "APPCODE " + EXP_APP_CODE);
        Map<String, String> querys = new HashMap<String, String>();
        querys.put("maxSize", "10000");
        querys.put("page", "1");
        List<Express> expressList = null;
        try {

            HttpResponse response = HttpUtils.doGet(API_HOST, EXP_LIST_PATH, EXP_METHOD, headers, querys);
            StatusLine statusLine = response.getStatusLine();
            if (statusLine.getStatusCode() != 200) {
                //获取失败则返回
                logger.info("get express list failure.:", statusLine.getStatusCode(), statusLine.getReasonPhrase());
                return;
            }

            String jsonStr = EntityUtils.toString(response.getEntity());
            expressList = parseResponseResult(jsonStr);
            //获取response的body
            //System.out.println(EntityUtils.toString(response.getEntity()));
        } catch (Exception e) {
            e.printStackTrace();
            logger.debug("can't not get the express list from remote server.");
            return;
        }

        //持入化到数据库
        if (expressList != null) {
            expressMapper.deleteExpressList();
            expressMapper.insertExpressList(expressList);
        }


    }


    private List<Express> parseResponseResult(String result) {

        ObjectMapper ob = new ObjectMapper();
        List<Express> expressList = null;
        try {
            JsonNode node = ob.readTree(result);
            JsonNode resBodyNode = node.get("showapi_res_body");
            JsonNode expressListNode = resBodyNode.get("expressList");
            ObjectMapper ob2 = new ObjectMapper();
            JavaType javaType = ob2.getTypeFactory().constructParametrizedType(ArrayList.class, List.class, Express.class);
            expressList = ob2.readValue(expressListNode.toString(), javaType);

        } catch (IOException e) {
            e.printStackTrace();
        }


        if (expressList != null) {
            expressList.toString();
            logger.debug("express parse success:", expressList);
        } else {
            logger.debug("expressList parse error");
        }

        return expressList;
    }

}
